package com.net

import android.os.Handler
import android.os.Looper
import com.net.interceptors.LoggerInterceptor
import com.net.parser.ObjectParser
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.util.concurrent.TimeUnit

/**
 * @describe:网络发动机 - 包括 执行请求，取消请求
 * @Author: lixiaopeng
 * @Date: 2020/6/28
 */
object NetClient {

    private var httpClient: OkHttpClient? = null
    private val handler = Handler(Looper.getMainLooper())

    fun getHttpClient(): OkHttpClient {
        if (httpClient == null) {
            synchronized(this) {
                if (httpClient == null) {
                    httpClient = OkHttpClient()
                }
            }
        }
        return httpClient as OkHttpClient
    }

    /**
     * 初始化
     */
    fun init(netClientConfig: NetClientConfig) {
        httpClient = OkHttpClient.Builder().apply {
            connectTimeout(netClientConfig.connectTimeout, TimeUnit.MILLISECONDS)
            readTimeout(netClientConfig.readTimeOut, TimeUnit.MILLISECONDS)
            writeTimeout(netClientConfig.writeTimeout, TimeUnit.MILLISECONDS)
            netClientConfig.cookieJar?.let {
                cookieJar(it)
            }
            if (netClientConfig.debug) {
                //添加日志管理拦截
                val tag = netClientConfig.tag ?: "NetUtils"
                eventListenerFactory(OKHttpEventListener.get(tag))
                addInterceptor(LoggerInterceptor(tag))
            }
            //添加本地拦截器
            if (netClientConfig.interceptors.isNotEmpty()) {
                netClientConfig.interceptors.forEach {
                    addInterceptor(it)
                }
            }
            //添加网络拦截器
            if (netClientConfig.netInterceptors.isNotEmpty()) {
                netClientConfig.netInterceptors.forEach {
                    addNetworkInterceptor(it)
                }
            }
        }.build()
    }

    /**
     * 取消请求
     */
    fun cancelTag(tag: Any) {
        NetUtils.getHttpClient().dispatcher.queuedCalls().forEach {
            if (it.request().tag()?.equals(tag) == true) {
                it.cancel()
            }
        }

        NetUtils.getHttpClient().dispatcher.runningCalls().forEach {
            if (it.request().tag()?.equals(tag) == true) {
                it.cancel()
            }
        }
    }

    /**
     * 取消请求
     */
    fun cancelRequest(request: Request) {
        getHttpClient().newCall(request).cancel()
    }

    /**
     * 同步执行
     */

    fun <T> execute(request: Request, parser: ObjectParser<T>?): T? {
        return parser?.buildResult()
    }

    /**
     * 异步执行
     */
    fun <T> enqueue(request: Request, parser: ObjectParser<T>?, success: ((t: T?) -> Unit)? = null, fail: ((msg: String) -> Unit)? = null) {
        getHttpClient().newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                fail?.let {
                    handler.post { it.invoke(e.message ?: "") }
                }
            }

            override fun onResponse(call: Call, response: Response) {
                if (parser == null) {
                    return
                }
                success?.let {
                    handler.post {
                        parser.responseStr = response.body?.string() ?: ""
                        it.invoke(parser.buildResult())
                    }
                }
            }
        })
    }
}